/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DataManager;

import Message.Base64;
import PIServer.LocalSettings;
import PIServer.VMSProtocolHandler;
import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DbManager {

    static final int MAX_DB_CONNECTION = 100;
    static final int MIN_DB_CONNECTION = 20;
    static final int NUMBER_OF_DB_PARTITION = 2;
    static final int DB_CONNECTION_TIMEOUT_IN_MS = 5*60*1000;
    static final int MAX_CONNECTION_AGE_IN_SEC = 60*60; // 1 hour

    static VCoreUserDataProvider vcClient = null;
    static MySQLCommonDataProvider commonDataProvider = null;
    static BoneCP connectionPool = null;

    public static Logger log = LoggerFactory.getLogger(DbManager.class.getName());

    public static VCoreUserDataProvider GetUserDataManager() {
        if (vcClient == null) {
            vcClient = new VCoreUserDataProvider();
        }
        return vcClient;
//        return new MySQLUserDataProvider();
    }

    public static MySQLCommonDataProvider GetCommonDataManager() {
        if (connectionPool == null) {
            initConnectionPool();
        }
        if (commonDataProvider==null) {
            commonDataProvider = new MySQLCommonDataProvider();
        }
        return commonDataProvider;
    }

    private static void initConnectionPool() {
        // setup the connection pool
        try {
            // load the database driver (make sure this is in your classpath!)
//            Class.forName("org.hsqldb.jdbcDriver");
            Class.forName("com.mysql.jdbc.Driver").newInstance();

            BoneCPConfig config = new BoneCPConfig();
            config.setJdbcUrl("jdbc:mysql://"+LocalSettings.DB_SERVER+"?&useUnicode=yes&characterEncoding=UTF-8");
            config.setUsername(Base64.toString(LocalSettings.DB_USERNAME));
            config.setPassword(Base64.toString(LocalSettings.DB_PASSWORD));
            config.setMaxConnectionAgeInSeconds(MAX_CONNECTION_AGE_IN_SEC);
            config.setPartitionCount(NUMBER_OF_DB_PARTITION);
            config.setMinConnectionsPerPartition(MIN_DB_CONNECTION/NUMBER_OF_DB_PARTITION);
            config.setMaxConnectionsPerPartition(MIN_DB_CONNECTION/NUMBER_OF_DB_PARTITION);
            config.setAcquireIncrement(5);
            config.setCloseConnectionWatch(true);
            config.setCloseConnectionWatchTimeoutInMs(DB_CONNECTION_TIMEOUT_IN_MS);
//            config.setLogStatementsEnabled(true);
            config.setConnectionTimeoutInMs(DB_CONNECTION_TIMEOUT_IN_MS);
            connectionPool = new BoneCP(config); // setup the connection pool
            if (connectionPool == null)
                throw new InternalError("Cannot create DB connection pool");
        } catch (Exception e) {
            VMSProtocolHandler.log.debug("Exception while creating DB connection pool",
                    e);
        }
    }
//    public String[] getConnectionString(int i){
//        return connStr;
//    }

    public static void shutdownConnectionPool() {
        connectionPool.shutdown(); // shutdown connection pool.
    }

    public static void getDBStatistics() {
        int totalFree = connectionPool.getStatistics().getTotalFree();
        int totalCreated = connectionPool.getStatistics().getTotalCreatedConnections();
        int totalLeased = connectionPool.getStatistics().getTotalLeased();
        log.info("DB-Pool stats: "+totalCreated+" created; "+totalLeased+" leased; "+totalFree+" free");
    }
}
